// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

package types2

import "cmd/compile/internal/syntax"

// ----------------------------------------------------------------------------------------
// API 

// 接口表示接口类型。
type Interface struct {
	check     *Checker      // 用于错误报告；nil once类型集计算
	obj       *TypeName     // 对应的声明对象；或者nil（更好的错误消息）
	methods   []*Func       // 显式声明方法的有序列表
	embeddeds []Type        // 显式嵌入元素的有序列表
	embedPos  *[]syntax.Pos // 嵌入元素的位置；或nil（对于错误消息）-使用指针来节省空间
	implicit  bool          // 接口是类型集文字（非接口T、~T或A | B）的包装器
	complete  bool          // 表示所有字段（tset除外）都已设置

	tset *_TypeSet // 此接口描述的类型集，延迟计算
}

// typeSet返回接口t的类型集。
func (t *Interface) typeSet() *_TypeSet { return computeInterfaceTypeSet(t.check, nopos, t) }

// emptyInterface表示空接口
var emptyInterface = Interface{complete: true, tset: &topTypeSet}

// NewInterfaceType返回给定方法和嵌入类型的新接口。
// NewInterfaceType拥有所提供方法的所有权，并且可以通过设置缺少的接收器来修改它们的类型
// 。
func NewInterfaceType(methods []*Func, embeddeds []Type) *Interface {
	if len(methods) == 0 && len(embeddeds) == 0 {
		return &emptyInterface
	}

	// 必要时设置方法接收器
	typ := (*Checker)(nil).newInterface()
	for _, m := range methods {
		if sig := m.typ.(*Signature); sig.recv == nil {
			sig.recv = NewVar(m.pos, m.pkg, "", typ)
		}
	}

	// 对API稳定性进行排序
	sortMethods(methods)

	typ.methods = methods
	typ.embeddeds = embeddeds
	typ.complete = true

	return typ
}

// 检查可能为零
func (check *Checker) newInterface() *Interface {
	typ := &Interface{check: check}
	if check != nil {
		check.needsCleanup(typ)
	}
	return typ
}

// 标记implicit将接口t标记为implicit，这意味着该接口
// 对应于一个约束文本，例如没有显式
// 接口嵌入的~t或a | B。在并发使用隐式接口之前，应先调用MarkImplicit。
func (t *Interface) MarkImplicit() {
	t.implicit = true
}

// NumExplicitMethods返回接口t显式声明的方法数。
func (t *Interface) NumExplicitMethods() int { return len(t.methods) }

// ExplicitMethod返回接口t的第i个显式声明的方法，其值为0<=i<t。NumExplicitMethods（）。
// 这些方法是按其唯一Id排序的。
func (t *Interface) ExplicitMethod(i int) *Func { return t.methods[i] }

// NumEmbeddeds返回接口t中嵌入类型的数量。
func (t *Interface) NumEmbeddeds() int { return len(t.embeddeds) }

// EmbeddedType返回接口t的第i个嵌入类型，0<=i<t。NumEmbeddeds（）。
func (t *Interface) EmbeddedType(i int) Type { return t.embeddeds[i] }

// NumMethods返回接口t的方法总数。
func (t *Interface) NumMethods() int { return t.typeSet().NumMethods() }

// Method返回0<=i<t.NumMethods（）的接口t的第i个方法。
// 这些方法按其唯一Id排序。
func (t *Interface) Method(i int) *Func { return t.typeSet().Method(i) }

// Empty报告t是否为空接口。
func (t *Interface) Empty() bool { return t.typeSet().IsAll() }

// IsCompable报告接口t的类型集中的每个类型是否具有可比性。
func (t *Interface) IsComparable() bool { return t.typeSet().IsComparable(nil) }

// IsMethodSet报告接口t是否完全由其方法集描述。
func (t *Interface) IsMethodSet() bool { return t.typeSet().IsMethodSet() }

// IsImplicit报告接口t是否是类型集文字的包装器。
func (t *Interface) IsImplicit() bool { return t.implicit }

func (t *Interface) Underlying() Type { return t }
func (t *Interface) String() string   { return TypeString(t, nil) }

// ----------------------------------------------------------------------------------------
// 实现

func (t *Interface) cleanup() {
	t.check = nil
	t.embedPos = nil
}

func (check *Checker) interfaceType(ityp *Interface, iface *syntax.InterfaceType, def *Named) {
	addEmbedded := func(pos syntax.Pos, typ Type) {
		ityp.embeddeds = append(ityp.embeddeds, typ)
		if ityp.embedPos == nil {
			ityp.embedPos = new([]syntax.Pos)
		}
		*ityp.embedPos = append(*ityp.embedPos, pos)
	}

	for _, f := range iface.MethodList {
		if f.Name == nil {
			addEmbedded(posFor(f.Type), parseUnion(check, f.Type))
			continue
		}
		// f.名称！=nil 

		// 我们有一个名为f.name的方法。jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie jie ji<pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad>；
		name := f.Name.Value
		if name == "_" {
			if check.conf.CompilerErrorMessages {
				check.error(f.Name, "methods must have a unique non-blank name")
			} else {
				check.error(f.Name, "invalid method name _")
			}
		}

		typ := check.typ(f.Type)
		sig, _ := typ.(*Signature)
		if sig == nil {
			if typ != Typ[Invalid] {
				check.errorf(f.Type, invalidAST+"%s is not a method signature", typ)
			}
		}

		var recvTyp Type = ityp
		if def != nil {
			recvTyp = def
		}
		sig.recv = NewVar(f.Name.Pos(), check.pkg, "", recvTyp)

		m := NewFunc(f.Name.Pos(), check.pkg, name, sig)
		check.recordDef(f.Name, m)
		ityp.methods = append(ityp.methods, m)
	}

	// 也就是说，这个接口可以用于类型集计算。
	ityp.complete = true

	if len(ityp.methods) == 0 && len(ityp.embeddeds) == 0 {
		// 空接口
		ityp.tset = &topTypeSet
		return
	}

	// 对API稳定性进行排序
	// （不要对嵌入项进行排序：它们必须对应于*EmbeddePos条目）
	sortMethods(ityp.methods)

	// 尽快计算类型集以报告任何错误。
	// 类型集的后续使用将使用此计算类型
	// 集，并且不需要传入*检查器。
	check.later(func() {
		computeInterfaceTypeSet(check, iface.Pos(), ityp)
	}).describef(iface, "compute type set for %s", ityp)
}
